package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.basic.entity.BasicMaterialsTypeDO;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicProductionStorageoutDAO;
import com.cssy.xxkj.logic.dao.LogicProductionStorageoutItemDAO;
import com.cssy.xxkj.logic.dao.LogicSalesDAO;
import com.cssy.xxkj.logic.dao.LogicSalesItemDAO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageoutDO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageoutItemDO;
import com.cssy.xxkj.logic.entity.LogicSalesDO;
import com.cssy.xxkj.logic.entity.LogicSalesItemDO;
import com.cssy.xxkj.logic.entity.vo.LogicSalesDetailVO;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.cssy.xxkj.logic.service.ILogicProductionStorageOutService;
import com.cssy.xxkj.logic.util.OftenMapUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;
@Service("logicProductionStorageOutService")
public class LogicProductionStorageOutServiceImpl implements ILogicProductionStorageOutService{
	private static final Logger logger = Logger.getLogger(LogicProductionStorageInServiceImpl.class);
	@Resource(name = "logicProductionStorageoutDAO")
	private LogicProductionStorageoutDAO logicProductionStorageoutDAO;
	
	@Resource(name = "logicProductionStorageoutItemDAO")
	private LogicProductionStorageoutItemDAO logicProductionStorageoutItemDAO;
	
	@Resource(name = "logicSalesDAO")
	private LogicSalesDAO logicSalesDAO;
	
	@Resource(name = "logicSalesItemDAO")
	private LogicSalesItemDAO logicSalesItemDAO;
	
	@Resource(name = "logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Resource(name = "oftenMapUtil")
	private OftenMapUtil oftenMapUtil;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicProductionStorageoutDO>  list= logicProductionStorageoutDAO.find(scs);
		rs.setRecordCount(logicProductionStorageoutDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		LogicProductionStorageoutDO basic = new LogicProductionStorageoutDO();
		basic.setBizModifyDate(new Date());
		basic.setBizModifyName(user.getName());
		basic.setId(id);
		basic.setRemoved(1l);
		return logicProductionStorageoutDAO.deleteBizRemoved(id);
	}

	@Override
	public Integer update(LogicProductionStorageoutDO t, User user) throws SyBaseException {
		t.setBizModifyDate(new Date());
		t.setBizModifyName(user.getName());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicProductionStorageoutDAO.updateLogicProductionStorageoutDO(t);
	}

	@Override
	public LogicProductionStorageoutDO save(LogicProductionStorageoutDO t, User user)
			throws SyBaseException {
		Date date=new Date();
		t.setBizCreatorName(user.getName());
		t.setBizCreatorDate(date);
		t.setBizVersion(1);
		logicProductionStorageoutDAO.insertLogicProductionStorageoutDO(t);
		return t;
	}

	@Override
	public LogicProductionStorageoutDO findListById(String id) throws SyBaseException {
		return logicProductionStorageoutDAO.findLogicProductionStorageoutDOByPrimaryKey(id);
	}

	@Override
	public void outSave(HttpServletRequest request,LogicProductionStorageoutDO curAP)
			throws SyBaseException {
		try{
			String json = request.getParameter("addressInfos");
			List<LogicProductionStorageoutItemDO> axxlist=JSONArray.parseArray(json, LogicProductionStorageoutItemDO.class);
			if(curAP!=null && StringUtils.isNotBlank(curAP.getId())){
				//修改
				if (curAP.getZd011BillStatus().equals(BillStatusUtil.PROSTOROUT_STATUS_FIVE)){
					//出库
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					LogicProductionStorageoutDO loi = logicProductionStorageoutDAO.findLogicProductionStorageoutDOByPrimaryKey(curAP.getId());
					for (LogicProductionStorageoutItemDO lii : axxlist){
						logicHsUtilService.processProdStorageOutItem(loi, lii, SessionUtil.getUser(request));
					}
				}else{
					String zd010OtherDate =request.getParameter("zd010OtherDate");
					curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
					int rt=0;
					rt=this.update(curAP, SessionUtil.getUser(request));
					if(0==rt){
						throw new SyBaseException("您修改的行数据发生改变！请重新打开查看");
					}
					logicProductionStorageoutItemDAO.deleteProById(curAP.getId());
					
					Map<String, Object> paramMap = new HashMap<String, Object>();
					paramMap.put("piCode", curAP.getZd003PiCode());
					paramMap.put("oriCode", curAP.getZd002OriCode());
					paramMap.put("whCode", curAP.getZd004WhCode());
					paramMap.put("billSt", BillStatusUtil.PROSTOROUT_STATUS_FIVE);
					Map<String, BigDecimal> hasQuantityMap = this.findStorageoutItemToMap(paramMap);
					Map<String , BasicMaterialsTypeDO> matTypeMap=this.oftenMapUtil.getMaterialTypeKeyMaterialCode(new SearchConditions());
					for (LogicProductionStorageoutItemDO lii : axxlist){
						//pi 仓库编码   code name spec model  quanlity color
						String keyStr =(StringUtils.isEmpty(curAP.getZd003PiCode())?null:curAP.getZd003PiCode())+"_"+
										(StringUtils.isEmpty(curAP.getZd004WhCode())?null:curAP.getZd004WhCode())+"_"+
										(StringUtils.isEmpty(lii.getZd002MaterialsCode())?null:lii.getZd002MaterialsCode())+"_"+
										(StringUtils.isEmpty(lii.getZd002MaterialsName())?null:lii.getZd002MaterialsName())+"_"+
										(StringUtils.isEmpty(lii.getZd016MaterialsSize())?null:lii.getZd016MaterialsSize())+"_"+
										(StringUtils.isEmpty(lii.getZd004MaterialsModel())?null:lii.getZd004MaterialsModel())+"_"+
										(StringUtils.isEmpty(lii.getZd018MaterialsQuality())?null:lii.getZd018MaterialsQuality())+"_"+
										(StringUtils.isEmpty(lii.getZd017MaterialsColor())?null:lii.getZd017MaterialsColor());
						BigDecimal canQuantity = BigDecimal.ZERO;
						BigDecimal theQuantity = lii.getZd007Quantity()==null?BigDecimal.ZERO:lii.getZd007Quantity();
						BigDecimal sumQuantity = lii.getZd021SalesQuanlity()==null?BigDecimal.ZERO:lii.getZd021SalesQuanlity();
						if(hasQuantityMap==null||hasQuantityMap.get(keyStr)==null){
							canQuantity = theQuantity;
						}else{
							canQuantity = theQuantity.add(hasQuantityMap.get(keyStr));
						}
						if(sumQuantity.subtract(canQuantity).compareTo(BigDecimal.ZERO)==-1){
							throw new SyBaseException("订单产品"+lii.getZd002MaterialsName()+"出库总数量大于订单数量，不合法！");
						}
						lii.setId(IDCodeTypeUtil.getId());
						lii.setZd001OtherOutId(curAP.getId());
						lii.setZd025Series(matTypeMap.get(lii.getZd002MaterialsCode())==null?
								null:matTypeMap.get(lii.getZd002MaterialsCode()).getZd002Name());
						logicProductionStorageoutItemDAO.insertLogicProductionStorageoutItemDO(lii);
					}
				}
			}else{
					curAP.setZd001OutCode(syCodeService.getCode(BillTypeConstant.PROOUT,BillTypeConstant.PROOUT,SyCode.DATE_YYMM,5));
					String id = IDCodeTypeUtil.getId();
					curAP.setId(id);
					String zd010OtherDate =request.getParameter("zd010OtherDate");
					curAP.setZd010OtherDate(DateUtils.stringToDate(zd010OtherDate));
					this.save(curAP, SessionUtil.getUser(request));
					Map<String , BasicMaterialsTypeDO> matTypeMap=this.oftenMapUtil.getMaterialTypeKeyMaterialCode(new SearchConditions());
					for (LogicProductionStorageoutItemDO lii : axxlist){
						lii.setId(IDCodeTypeUtil.getId());
						lii.setZd001OtherOutId(id);
						lii.setZd025Series(matTypeMap.get(lii.getZd002MaterialsCode())==null?
								null:matTypeMap.get(lii.getZd002MaterialsCode()).getZd002Name());
						logicProductionStorageoutItemDAO.insertLogicProductionStorageoutItemDO(lii);
					}
			}
			logger.info("操作销售出库成功");
			if(curAP.getZd011BillStatus().equals(BillStatusUtil.PROSTOROUT_STATUS_FIVE)){
				LogicProductionStorageoutDO out =this.findListById(curAP.getId());
				LogicSalesDO plan = new LogicSalesDO();
				plan.setZd001FormCode(out.getZd002OriCode());
				List<LogicSalesDO> planlist=logicSalesDAO.findListByExample(plan);
				if(planlist!=null&&!planlist.isEmpty()&&planlist.size()>0){
					/*if(this.validateReturn(this.findByIdItem(curAP,false), planlist.get(0).getId())){
						planlist.get(0).setZd025WareStatus(2);
					}else{
						planlist.get(0).setZd025WareStatus(1);
					}*/
					LogicSalesDO sale = planlist.get(0);
					if(validateCompletSale(out)){
						sale.setZd025WareStatus(2);
					}else{
						sale.setZd025WareStatus(1);
					}
					sale.setBizVersionMark(sale.getBizVersion());
					sale.setBizVersion(sale.getBizVersion()+1);
					int r=logicSalesDAO.updateLogicSalesDO(sale);
					if(r==0){
						throw new SyBaseException("您操作的原始单据数据发生了改变!请您重新打开编辑！");
					}
					logger.info("更新销售订单出库状态成功");
				}
			}
		}catch(Exception e){
			e.printStackTrace();
			logger.info("操作销售出库失败");
			throw new SyBaseException(GlobalResLoader.getOpfailed()
					+ e.getMessage());
		}
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicProductionStorageoutDAO.deleteBizRemoved(id);
	}

	@Override
	public List<LogicProductionStorageoutItemDO> findStorOutItemList(String inId)
			throws SyBaseException {
		SearchConditions scs = new SearchConditions();
		scs.setRemovedProperty(null);
		scs.addCondition("zd001OtherOutId", inId, SearchCondition.OP_EQUAL);
		if (scs.getOrderBy()==null) {
			scs.setOrderBy("(zd023Order + 0 )");
		}
		List<LogicProductionStorageoutItemDO>  list=logicProductionStorageoutItemDAO.find(scs);
		return list;
	}
	
	@Override
	public Map<String, BigDecimal> findStorageoutItemToMap(Map<String, Object> paramMap)throws SyBaseException{
		List<LogicProductionStorageoutItemDO> outItemList = logicProductionStorageoutItemDAO.findListByMap(paramMap);
		if(outItemList==null||outItemList.isEmpty()||outItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> hasSgeoutItemMap = new HashMap<String, BigDecimal>();
			for(LogicProductionStorageoutItemDO outItem : outItemList){
				if(outItem==null||StringUtils.isBlank(outItem.getId())){
					continue;
				}
				if("c0688".equals(outItem.getZd002MaterialsCode())&&
						"深灰色".equals(outItem.getZd017MaterialsColor())&&
								"183*135".equals(outItem.getZd016MaterialsSize())){
					System.out.println();
				}
				//pi 仓库编码   code name spec model  quanlity color
				String keyStr=(StringUtils.isEmpty(paramMap.get("piCode")+"")?null:paramMap.get("piCode")+"")+"_"+
								(StringUtils.isEmpty(paramMap.get("whCode")+"")?null:paramMap.get("whCode")+"")+"_"+
								(StringUtils.isEmpty(outItem.getZd002MaterialsCode())?null:outItem.getZd002MaterialsCode())+"_"+
								(StringUtils.isEmpty(outItem.getZd002MaterialsName())?null:outItem.getZd002MaterialsName())+"_"+
								(StringUtils.isEmpty(outItem.getZd016MaterialsSize())?null:outItem.getZd016MaterialsSize())+"_"+
								(StringUtils.isEmpty(outItem.getZd004MaterialsModel())?null:outItem.getZd004MaterialsModel())+"_"+
								(StringUtils.isEmpty(outItem.getZd018MaterialsQuality())?null:outItem.getZd018MaterialsQuality())+"_"+
								(StringUtils.isEmpty(outItem.getZd017MaterialsColor())?null:outItem.getZd017MaterialsColor());
				BigDecimal out = outItem.getZd007Quantity()==null?BigDecimal.ZERO:outItem.getZd007Quantity();
				BigDecimal back= outItem.getZd007BackQuantity()==null?BigDecimal.ZERO:outItem.getZd007BackQuantity();
				BigDecimal outQuantity=out.subtract(back);
				if(hasSgeoutItemMap.get(keyStr)==null){
					hasSgeoutItemMap.put(keyStr, outQuantity);
				}else{
					hasSgeoutItemMap.put(keyStr, outQuantity.add(hasSgeoutItemMap.get(keyStr)));
				}
			}
			return hasSgeoutItemMap;
		}
	}
	
	/**
	 * 验证是否完全出库
	 * @param stogrageOut
	 * @return
	 */
	private boolean validateCompletSale(LogicProductionStorageoutDO stogrageOut){
		boolean completSale = true;
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("formCode", stogrageOut.getZd002OriCode());
		List<LogicSalesItemDO> saleItemList = logicSalesItemDAO.findListByMap(paramMap);
		
		paramMap.clear();
		paramMap.put("piCode", stogrageOut.getZd003PiCode());
		paramMap.put("whCode", stogrageOut.getZd004WhCode());
		paramMap.put("oriCode", stogrageOut.getZd002OriCode());
		paramMap.put("billSt", BillStatusUtil.PROSTOROUT_STATUS_FIVE);
		Map<String, BigDecimal> hasQuantityMap = this.findStorageoutItemToMap(paramMap);
		for(LogicSalesItemDO saleItem : saleItemList){
			if(saleItem==null||StringUtils.isBlank(saleItem.getId())){
				continue;
			}//pi 仓库编码   code name spec model  quanlity color
			String keyStr = (StringUtils.isEmpty(paramMap.get("piCode")+"")?null:paramMap.get("piCode")+"")+"_"+
								(StringUtils.isEmpty(paramMap.get("whCode")+"")?null:paramMap.get("whCode")+"")+"_"+
								(StringUtils.isEmpty(saleItem.getZd007MaterialsCode())?null:saleItem.getZd007MaterialsCode())+"_"+
								(StringUtils.isEmpty(saleItem.getZd008MaterialsName())?null:saleItem.getZd008MaterialsName())+"_"+
								(StringUtils.isEmpty(saleItem.getZd038MaterialsSize())?null:saleItem.getZd038MaterialsSize())+"_"+
								(StringUtils.isEmpty(saleItem.getZd010MaterialsModel())?null:saleItem.getZd010MaterialsModel())+"_"+
								(StringUtils.isEmpty(saleItem.getZd042MaterialsQuality())?null:saleItem.getZd042MaterialsQuality())+"_"+
								(StringUtils.isEmpty(saleItem.getZd041MaterialsColor())?null:saleItem.getZd041MaterialsColor());			
			BigDecimal hasQuantity = hasQuantityMap.get(keyStr);
			if(hasQuantity==null){
				hasQuantity = BigDecimal.ZERO;
			}
			BigDecimal saleQuantity = saleItem.getZd013Quantity()==null?BigDecimal.ZERO:saleItem.getZd013Quantity();
			int compUp = saleQuantity.subtract(hasQuantity).compareTo(BigDecimal.ZERO);
			if(compUp==1){
				completSale = false;
			}
		}
		
		return completSale;
	}
	
	@Override
	public SearchResult findQuerySaleDetailByScs(SearchConditions scs)throws SyBaseException{
		SearchResult rs=new SearchResult(scs);
		List<LogicSalesDetailVO> list = logicProductionStorageoutDAO.findQuerySaleDetailByScs(scs);
		rs.setRecordCount(logicProductionStorageoutDAO.countQuerySaleDetailByScs(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public List<LogicProductionStorageoutItemDO> findStorOutItemListByMap(
			Map<String, Object> paramMap) throws SyBaseException {
		return this.logicProductionStorageoutItemDAO.findListByMap(paramMap);
	}
	
}
